/* 小程序操作云数据库（待测试） */
const { env, db_options } = require('config')
const app = getApp()
const db = wx.cloud.database()

/* 请求前置处理 */
function preHandler(options={}) {
  options = Object.assign(db_options, options)
  // 登录检查
  if (options.login && !app.isLogin()) {
    wx.showModal({
      title: options.loginTitle,
      content: options.loginText,
      success: res => {
        res.confirm && wx.switchTab({
          url: options.loginPage
        })
      }
    })
    return false
  }
  // 加载动画
  options.loading && wx.showLoading({
    title: options.loading
  })
  return options
}

/**
 * 新增一条记录
 * @param {String} dbname 集合名
 * @param {Object} data 数据
 * @param {Object} options 选项
 */
function add(dbname, data, options={}) {
  return new Promise((resolve, reject) => {
    // 前置处理
    options = preHandler(options)
    if (!options) return reject()
    // 发起请求
    db.collection(dbname).add({
      data,
      success: res => {
        options.success && wx.showToast({ title: '保存成功' })
        resolve(res)
      },
      fail: err => {
        var debug = app.global.user && app.global.user.role === 'admin' || env === 'dev'
        wx.showToast({
          icon: 'none',
          title: debug ? `[集合${dbname}][添加记录]失败` : '请求失败',
        })
        reject(err)
      },
      complete: () => {
        options.loading && wx.hideLoading()
      }
    })
  })
}

/**
 * 删除一条记录
 * @param {String} dbname 
 * @param {String} id 
 * @param {Object} options 
 */
function remove(dbname, id, options) {
  return new Promise((resolve, reject) => {
    // 前置处理
    options = preHandler(options)
    if (!options) return reject()
    // 发起请求
    db.collection(dbname).doc(id).remove({
      success: res => {
        options.success && wx.showToast({ title: '删除成功' })
        resolve(res)
      },
      fail: err => {
        var debug = app.global.user && app.global.user.role === 'admin' || env === 'dev'
        wx.showToast({
          icon: 'none',
          title: debug ? `[集合${dbname}][删除记录]失败` : '请求失败',
        })
        reject(err)
      },
      complete: () => {
        options.loading && wx.hideLoading()
      }
    })
  })
}

/**
 * 修改一条记录
 * @param {String} dbname 集合名
 * @param {Object} data 数据（不能包含_id）
 * @param {Object} options 选项
 */
function update(dbname, data, options) {
  return new Promise((resolve, reject) => {
    // 前置处理
    options = preHandler(options)
    if (!options) return reject()
    // 利用 json 实现简单对象的深拷贝, 防止删除 _id 对外部对象产生影响
    data = JSON.parse(JSON.stringify(data))
    // 暂存_id, 待更新字段不能带有 _id
    let _id = data._id
    delete data._id
    // 发起请求
    db.collection(dbname).doc(_id).update({
      data,
      success: res => {
        options.success && wx.showToast({ title: '保存成功' })
        resolve(res)
      },
      fail: err => {
        var debug = app.global.user && app.global.user.role === 'admin' || env === 'dev'
        wx.showToast({
          icon: 'none',
          title: debug ? `[集合${dbname}][更新记录]失败` : '请求失败',
        })
        reject(err)
      },
      complete: () => {
        options.loading && wx.hideLoading()
      }
    })
  })
}

/**
 * 根据id修改某个属性
 * @param {*} dbname 集合名
 * @param {*} id 对象id
 * @param {*} data 属性数据
 * @param {*} options 选项
 */
function updateById(dbname, id, data, options) {
  return new Promise((resolve, reject) => {
    // 前置处理
    options = preHandler(options)
    if (!options) return reject()
    // 利用 json 实现简单对象的深拷贝, 防止删除 _id 对外部对象产生影响
    data = JSON.parse(JSON.stringify(data))
    // 暂存_id, 待更新字段不能带有 _id
    let _id = data._id
    delete data._id
    // 发起请求
    db.collection(dbname).doc(id).update({
      data,
      success: res => {
        options.success && wx.showToast({ title: '保存成功' })
        resolve(res)
      },
      fail: err => {
        var debug = app.global.user && app.global.user.role === 'admin' || env === 'dev'
        wx.showToast({
          icon: 'none',
          title: debug ? `[集合${dbname}][更新记录]失败` : '请求失败',
        })
        reject(err)
      },
      complete: () => {
        options.loading && wx.hideLoading()
      }
    })
  })
}

/**
 * 根据ID查询记录
 * @param {String} dbname 
 * @param {String} id 
 * @param {Object} options 
 */
function findById(dbname, id, options) {
  return new Promise((resolve, reject) => {
    // 前置处理
    options = preHandler(options)
    if (!options) return reject()
    // 发起请求
    db.collection(dbname).doc(id).get({
      success: res => resolve(res),
      fail: err => {
        var debug = app.global.user && app.global.user.role === 'admin' || env === 'dev'
        wx.showToast({
          icon: 'none',
          title: debug ? `[集合${dbname}][查询记录]失败` : '请求失败',
        })
        reject(err)
      },
      complete: () => {
        options.loading && wx.hideLoading()
      }
    })
  })
}

/**
 * 根据条件查询记录(小程序端最多一次查询10条记录)
 * @param {String} dbname 
 * @param {Object} params 
 * @param {Object} options 
 */
function findByPage(dbname, params, page=1, size=10, options) {
  return new Promise((resolve, reject) => {
    // 前置处理
    options = preHandler(options)
    if (!options) return reject()
    // 参数准备
    let begin = (page - 1) * size
    // 发起请求
    db.collection(dbname)
    .where({  ...params })
    .orderBy('addtime', 'desc')
    .skip(begin)
    .limit(size)
    .get({
      success: res => resolve(res),
      fail: err => {
        var debug = app.global.user && app.global.user.role === 'admin' || env === 'dev'
        wx.showToast({
          icon: 'none',
          title: debug ? `[集合${dbname}][查询记录]失败` : '请求失败',
        })
        reject(err)
      },
      complete: () => {
        options.loading && wx.hideLoading()
      }
    })
  })
}

module.exports = {
  add,
  update,
  updateById,
  remove,
  findById,
  findByPage
}
